﻿using System;
using System.Collections.Generic;
using System.Linq;
using BusinessBingo.Model;

namespace BusinessBingo.Data
{
    /// <summary>
    /// Mapper between model and EF-model
    /// </summary>
    public static class Mapping
    {
        public static Model.Conference MapConference(Data.Conference conference)
        {
            Model.Conference result = new Model.Conference();
            result.Id = conference.Id;
            result.Name = conference.Name;

            return result;
        }

        /// <summary>
        /// Map Data.Group to Model.Group
        /// </summary>
        /// <param name="dataGroup">DataGroup input</param>
        /// <returns>Returns the mapped model group</returns>
        public static Model.Group MapGroup(Data.Group dataGroup)
        {
            Model.Group group = new Model.Group();

            group.Id = dataGroup.Id;
            group.Name = dataGroup.Name;
            group.Url = dataGroup.Url;
            group.Language = (LanguageKey) Convert.ToInt32(dataGroup.LCID);

            return group;
        }

        public static Data.Group MapGroup(Model.Group modelG)
        {
            Data.Group group = new Data.Group();

            group.Id = modelG.Id;
            group.Name = modelG.Name;
            group.Url = modelG.Url;
            group.LCID = ((int) modelG.Language).ToString();

            return group;
        }

        public static Model.Game MapGame(Data.Game game)
        {
            Model.Game result = new Model.Game();
            result.Id = game.Id;
            result.Number = game.Number;
            result.GroupId = game.GroupId;

            return result;
        }

        public static Model.User MapSessionUser(Data.SessionUser dataSessionUser)
        {
            Model.User user = new User();

            user.Id = dataSessionUser.Id;
            user.Name = dataSessionUser.Name;
            user.Finished = dataSessionUser.Finished;

            return user;
        }

        public static Data.SessionUser MapSessionUser(Model.User modelUser)
        {
            Data.SessionUser user = new Data.SessionUser();

            user.Id = modelUser.Id;
            user.Name = modelUser.Name;
            user.Finished = modelUser.Finished;

            return user;
        }

        public static LanguageKey MapLcid(string lcid)
        {
            switch(lcid)
            {
                case "1031":
                    return LanguageKey.De;
                case "1033":
                    return LanguageKey.En;
                default:
                    throw new ArgumentException(string.Format("Invalid Lcid {0}", lcid));
            }
        }

        public static string MapLanguage(LanguageKey language)
        {
            switch (language)
            {
                case LanguageKey.De:
                    return "1031";
                case LanguageKey.En:
                    return "1033";
                default:
                    throw new ArgumentException(string.Format("Invalid LanguageKey {0}", language));
            }
        }

        public static Model.Word MapWord(Data.Word dataWord)
        {
            Model.Word word = new Model.Word();

            word.Id = dataWord.Id;
            word.Value = dataWord.Value;
            word.Upvotes = dataWord.Upvotes;
            word.Downvotes = dataWord.Downvotes;
            word.Language = Mapping.MapLcid(dataWord.LCID);

            return word;
        }

        public static Data.Word MapWord(Model.Word modelWord)
        {
            Data.Word word = new Data.Word();

            word.Id = modelWord.Id;
            word.Value = modelWord.Value;
            word.Upvotes = modelWord.Upvotes;
            word.Downvotes = modelWord.Downvotes;
            return word;
        }
        
        public static IList<Model.BingoSet> MapBingoSets(IList<BingoSet> bingoSets)
        {
            IList<Model.BingoSet> results = new List<Model.BingoSet>();

            foreach (BingoSet bs in bingoSets)
            {
                results.Add(Mapping.MapBingoSet(bs));
            }

            return results;
        }

        public static Model.BingoSet MapBingoSet(Data.BingoSet bingoSet)
        {
            Model.BingoSet bs = new Model.BingoSet();

            bs.UserId = bingoSet.SessionUserId;
            bs.GameId = bingoSet.GameId;

            if (bingoSet.BingoWordSets.IsLoaded == true && bingoSet.BingoWordSets.Count > 0)
            {
                bs.WordPositions = Mapping.MapBingoWordSets(bingoSet.BingoWordSets.ToList());
                bs.WordPositions = bs.WordPositions.OrderBy(x => x.PositionX).ThenBy(y => y.PositionY).ToList();
                bs.Size = bs.WordPositions.Max(x => x.PositionX) + 1; //add 1, because Positions are zero-based
                bs.Language = bs.WordPositions.First().Word.Language;
            }

            return bs;
        }

        public static IList<WordPosition> MapBingoWordSets(IList<BingoWordSet> bingoWordSets)
        {
            IList<WordPosition> wordPositions = new List<WordPosition>();
            foreach(BingoWordSet bingoWordSet in bingoWordSets)
            {
                wordPositions.Add(Mapping.MapBingoWordSet(bingoWordSet));
            }
            return wordPositions;
        }

        public static Model.WordPosition MapBingoWordSet(Data.BingoWordSet dataBingoWordSet)
        {
            Model.WordPosition wordPosition = new WordPosition();

            if (dataBingoWordSet.Word != null)
            {
                wordPosition.Word = MapWord(dataBingoWordSet.Word);
            }

            wordPosition.Checked = dataBingoWordSet.Checked;
            wordPosition.PositionX = dataBingoWordSet.WordPositionX;
            wordPosition.PositionY = dataBingoWordSet.WordPositionY;

            return wordPosition;
        }
    }
}
